/**
 * Date: 2025/10/11
 * Author: QI
 * Description: define object: OPC, alu_Info, OpInfo
 */
package empty.dsa.util
import scala.collection.mutable.ListBuffer

/**
 * OPC: operation code
 */
object OPC extends Enumeration {
    type OPC = Value
    val md5,
    sha1,
    sha256,
    sm3,
    sha224,
    sha384_32,
    sha384_64,
    aes128 = Value

    val numOPC = this.values.size
    def printOPC = {
        this.values.foreach( op => println(s"$op\t: ${op.id}"))
    }
}

/**
 * alu_Info: alu info
 */
object alu_Info { 
    val sha1_penumMap: Map[Int, List[Int]] = Map(
        //pe_num -> kt中seq的元素个数
        80 -> List(1),
        40 -> List(2),
        20 -> List(4),
        16 -> List(4),
        8  -> List(4),
        5  -> List(4),
        4  -> List(4),
        2  -> List(4),
        1  -> List(4)
    )
}

/**
 * op_Info: op info
 */
object OpInfo {
    val OpInfoMap: Map[OPC.OPC, List[Int]] = Map(
        //in_num, out_num, cycle, DPM_outnum, DPM_out_data
        OPC.sha1 -> List(7,6,80,1,80),
    )

    val String2IntMap : Map[String,Int] = Map(
        "md5" -> OPC.md5.id,
        "sha1" -> OPC.sha1.id,
    )

    val opInt2StringMap : Map[Int, String] = Map(
        0 -> "md5",
        1 -> "sha1"
    )

    /**
     * 获取ALU的输入参数个数
     */
    def getALUinNum(op: OPC.OPC): Int = {
        val info = OpInfo.OpInfoMap(op)
        info(0)
    }
    /**
     * 获取ALU的输出参数个数
     */
    def getALUoutNum(op: OPC.OPC): Int = {
        val info = OpInfo.OpInfoMap(op)
        info(1)
    }
    /**
     * 获取操作时钟周期
     */
    def getOperandCycle(op: OPC.OPC): Int = {
        val info = OpInfo.OpInfoMap(op)
        info(2)
    }
    /**
     * 获取DPM的输出参数个数
     */
    def getDPMoutNum(op: OPC.OPC): Int = {
        val info = OpInfo.OpInfoMap(op)
        info(3)
    }
    /**
     * 获取DPM的输出数据
     */
    def getDPMOutData(op: OPC.OPC): Int = {
        val info = OpInfo.OpInfoMap(op)
        info(4)
    }
    /**
     * 获取操作数对应的OPC
     * @param op
     * @return
     */
    def fuget(op : Int) : ListBuffer[OPC.OPC] = {
        val oplist = new ListBuffer[OPC.OPC]
        for (i <- 0 until OPC.numOPC) {
            if((op & (1 << i)) > 0) {
                oplist.append(OPC(i))
            }
        }
        oplist
    }

}

